package com.collabscm.pf.util;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.collabscm.pf.CommonConstants;
import com.collabscm.pf.auth.UserInfo;
import com.collabscm.pf.cache.Cache;
import com.collabscm.pf.cache.CacheManager;
import com.collabscm.pf.cache.CacheManagerFactory;
import com.collabscm.pf.logging.Logger;
import com.collabscm.pf.logging.LoggerFactory;
import com.collabscm.pf.model.DomainObject;

/**
 * 对象相关的工具类
 * @author Zeng Raoxing
 */
public class ObjectUtils {
	private static Logger logger = LoggerFactory.getLogger(ObjectUtils.class);
	
	/**
	 * 通用的toString方法，首先判断此类自己是否覆盖了Object的默认的toString方法，
	 * 如果有自定义的toString方法，那么就调用自己的toString方法。
	 * 
	 * @param obj 待toString的方法
	 */
	public static String toString(Object obj) {
		Class<?> clazz = obj.getClass();
		String className = clazz.getName();
		ObjectSerializable<Method> os = toStringCache.get(className);
		//是否执行默认的toString方法。
		boolean isDefault = true;
		Method m = null;
		if(os != null) {
			if(os.getObject() != null) {
				isDefault = false;
				m = os.getObject();
			}
		} else {
			m = ReflectionUtils.getMethod(obj.getClass(), "toString");
			clazz = m.getDeclaringClass();
			if(clazz == Object.class) {
				//如果不是自定义的toString方法，那么就设置为null
				toStringCache.put(className, null);
			} else {
				toStringCache.put(className, new ObjectSerializable<Method>(m));
				isDefault = false;
			}
		}
		logger.debug("从缓存中取得对象为{}，其对应的Method对象为{}，当前isDefault为{}。", os, m, isDefault);
		if(isDefault) {
			return defaultToString(obj);
		} else {
			return (String) ReflectionUtils.invokeMethod(m, obj);
		}
	}
	
	/**
	 * toString方法的缓存
	 */
	private static Cache<String, ObjectSerializable<Method>> toStringCache;
	
	/**
	 * 默认的toString方法。
	 * 
	 * @param obj
	 * @return
	 */
	public static String defaultToString(Object obj) {
		return new ReflectionToStringBuilder(obj, ToStringStyle.DEFAULT_STYLE).toString();
	}
	
	static {
		@SuppressWarnings("unchecked")
		CacheManager<Cache<String, ObjectSerializable<Method>>> cm = CacheManagerFactory.getCacheManager();
		toStringCache = cm.getCache("platform/utils/ObjectUtils");
	}
	
	/**
	 * 对象数据转化为String
	 * @param objects
	 * @return
	 */
	public static String arrayToString(Object[] objects) {
		return Arrays.toString(objects);
	}
	
	/**
	 * 往DomainObject中设置创建相关信息
	 * 
	 * @param domainObject
	 */
	public static void fillCreateInfo(DomainObject domainObject) {
		Date current = RuntimeContext.getCurrentDate();
		UserInfo userInfo = RuntimeContext.getCurrentUserInfo();
		domainObject.setCreator(userInfo.getUserId());
		domainObject.setCreatedTime(current);
		domainObject.setLastUpdator(userInfo.getUserId());
		domainObject.setLastUpdatedTime(current);
		domainObject.setStatus(CommonConstants.STATUS_ENABLE);
	}
	
	/**
	 * 填充DomainObject的更新信息
	 * 
	 * @param domainObject
	 */
	public static void fillUpdateInfo(DomainObject domainObject) {
		fillUpdateInfo(domainObject, false);
	}
	
	/**
	 * 填充DomainObject的更新信息
	 * 
	 * @param domainObject
	 * @param isDelete
	 */
	public static void fillUpdateInfo(DomainObject domainObject, boolean isDelete) {
		Date current = RuntimeContext.getCurrentDate();
		UserInfo userInfo = RuntimeContext.getCurrentUserInfo();
		domainObject.setLastUpdator(userInfo.getUserId());
		domainObject.setLastUpdatedTime(current);
		if(isDelete) {
			domainObject.setStatus(CommonConstants.STATUS_ENABLE);
		} else {
			domainObject.setStatus(CommonConstants.STATUS_DISABLE);
		}
	}

}
